﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using System.Text;

namespace Common.Json
{
    /// <summary>
    /// 枚举属性转换，如果属性类型是枚举，此转换器会为Json加多一个“属性名”+“Text"的Json字段
    /// </summary>
    public class EnumPropertyConverter : JsonConverter
    {
        /// <summary>
        /// 是否能序列化
        /// </summary>
        /// <param name="objectType"></param>
        /// <returns></returns>
        public override bool CanConvert(Type objectType)
        {
            return objectType.IsEnum;
        }
        /// <summary>
        /// 反序列
        /// </summary>
        /// <param name="reader"></param>
        /// <param name="objectType"></param>
        /// <param name="existingValue"></param>
        /// <param name="serializer"></param>
        /// <returns></returns>
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer)
        {
            if (objectType.IsEnum)
            {
                return Enum.Parse(objectType, reader.Value?.ToString());
            }
            return reader.Value;
        }
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="value"></param>
        /// <param name="serializer"></param>
        public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer)
        {
            writer.WriteValue(value);
            try
            {
                string path = writer.Path;
                if (path.Contains("."))
                {
                    path = path.Substring(path.LastIndexOf(".") + 1);
                }

                Type enumType = value.GetType();
                string enumText = value.ToString();
                if (Enum.IsDefined(enumType, value))
                {
                    string enumName = Enum.GetName(enumType, value);
                    FieldInfo field = enumType.GetField(enumName);
                    if (field.GetCustomAttribute(typeof(DisplayAttribute)) is DisplayAttribute attr)
                    {
                        enumText = attr.Name;
                    }
                }
                if (writer.WriteState != WriteState.Array)
                {
                    writer.WritePropertyName(path + "Text");
                    writer.WriteValue(enumText);
                }
            }
            catch
            {

            }
        }
    }
}
